// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.appengine.preferencessync.internal.network;

import com.google.appengine.preferencessync.adapter.AbstractSyncablePrefsService.RequestProcessor;
import com.google.appengine.preferencessync.internal.Config;
import com.google.appengine.preferencessync.internal.InternalSyncException;
import com.google.appengine.preferencessync.internal.InternalSyncException.ExceptionType;
import com.google.appengine.syncserver.shared.ClientIdRequest;
import com.google.appengine.syncserver.shared.ClientIdResponse;
import com.google.appengine.syncserver.shared.HttpParameterDefinitions.ClientRequest;

import android.util.Log;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;

import java.io.IOException;

/**
 * Class to get a new client id from the server.
 */
public class ClientIdUtils {

  /**
   * Get client id from the server. This is should be called only when a new user set and also when
   * the application gets installed for the first time.
   *
   * @throws InternalSyncException
   */
  private static long getClientId(String rootUrl, String username, RequestProcessor request)
      throws InternalSyncException {

    // TODO(chintanraoh): remove to string and pass the ClientIdRequests super
    // type.
    String response = HttpUtils.sendRequest(request, rootUrl, ClientRequest.CLIENT_ID_REQUEST,
        new ClientIdRequest(username).toString());

    if (response == null) {
      // TODO(chintanraoh): Make sure that you throw and exception when
      // you have to.
      return -1;
    }

    Exception exception = null;
    long clientId = 0;
    try {
      clientId = ClientIdResponse.valueOf(response).getClientId();
    } catch (JsonParseException e) {
      exception = e;
    } catch (JsonMappingException e) {
      exception = e;
    } catch (IOException e) {
      exception = e;
    }
    if (exception != null) {
      throw new InternalSyncException(exception, ExceptionType.INTERNAL_EXCEPTION,
          exception.getMessage(), Log.ERROR);
    }
    return clientId;
  }

  /**
   * Get client id from the server if you have not got it before.
   *
   * @param config The config to be passed to the server.
   * @throws InternalSyncException
   */
  public static void mayBeSetClientId(Config config, RequestProcessor requestProcessor)
      throws InternalSyncException {
    if (config.getClientId() == -1) {

      if (config.getUsername() == null) {
        throw new InternalSyncException(ExceptionType.INTERNAL_EXCEPTION,
            InternalSyncException.USERNAME_NAME_NOT_SET, Log.WARN);
      }

      config.setClientId(getClientId(config.getRootUrl(), config.getUsername(), requestProcessor));
    }
  }
}
